package com.yhn.shortlink.common.biz;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSON;
import com.yhn.shortlink.common.constant.RedisConstant;
import com.yhn.shortlink.common.constant.UserConstant;
import com.yhn.shortlink.common.enums.UserErrorEnums;
import com.yhn.shortlink.common.exception.BusinessException;
import jakarta.servlet.*;
import jakarta.servlet.http.HttpServletRequest;

import lombok.RequiredArgsConstructor;
import org.springframework.data.redis.core.StringRedisTemplate;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * 用户信息传输过滤器
 *
 * @author yhn
 * @version 1.0
 * @description
 * @date 2024/7/25 14:37
 */
@RequiredArgsConstructor
public class UserTransmitFilter implements Filter {

    private final StringRedisTemplate stringRedisTemplate;

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
            throws IOException, ServletException {
        HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;

        String uri = httpServletRequest.getRequestURI();
        if (!isIgnoredUrl(uri)) {
            String token = httpServletRequest.getHeader(UserConstant.USER_TOKEN);
            String username = httpServletRequest.getHeader(UserConstant.USER_USERNAME);
            if(!StrUtil.isAllNotBlank(username, token)){
                //username或token为空
                throw new BusinessException(UserErrorEnums.USER_FAIL_TOKEN);
            }
            //从redis获取信息
            Object userInfoJson = stringRedisTemplate.opsForHash().get(RedisConstant.USER_LOGIN_KEY_PREFIX + username, token);
            if (userInfoJson != null) {
                UserInfoDTO userInfoDTO = JSON.parseObject(userInfoJson.toString(), UserInfoDTO.class);
                UserContext.setUser(userInfoDTO);
            } else {
                throw new BusinessException(UserErrorEnums.USER_FAIL_TOKEN);
            }
        }
        try {
            filterChain.doFilter(servletRequest, servletResponse);
        } finally {
            UserContext.removeUser();
        }
    }

    private boolean isIgnoredUrl(String uri) {
        List<String> ignoreUrls = new ArrayList<>();
        ignoreUrls.add("/api/doc.html");
        ignoreUrls.add("/api/user/login");
        ignoreUrls.add("/api/user/register");
        ignoreUrls.add("/api/user/hasUserName");
        // 添加对所有以"/api/webjars"开头的URL的放行逻辑
        return ignoreUrls.contains(uri) || uri.startsWith("/api/webjars") || uri.startsWith("/api/v3");
    }
}
